#!/usr/bin/env python

import os
from os3.types.dotdict import dotdict

class _remap_cfg ( object ):
	def __init__ ( self, cfg, liwe_cfg ):
		self.cfg = cfg
		self.liwe_cfg = liwe_cfg

	def get ( self, name, def_val = None ):
		return self.cfg.get ( name, self.liwe_cfg.get ( name, def_val ) )

class LiweModule ( object ):
	def __init__ ( self, liwe, name ):
		self.liwe = liwe
		self.name = name
		self.pyhp = liwe.pyhp

		self.site_id = liwe.cfg.get ( "site.id", 0 )

		module_db = "MODULE_%s_DB" % name.upper ()

		self.templates = {}
		self.cbacks = {}
		self.config = {}

		# NEW: configurazione del singolo modulo
		#self.__cfg = dotdict ( liwe.cfg.get ( "modules." + name, {} ) )
		self.cfg = _remap_cfg ( dotdict ( liwe.cfg.get ( "modules." + name, {} ) ), liwe.cfg )

		if liwe.cfg.get ( module_db ):
			self.dbm = self.liwe.get_dbm ( liwe.cfg.get ( module_db ) )
		else:
			self.dbm = self.liwe.dbm

		# Load module HTML templates 
		self._load_templates ()

		# Load module default config
		self._load_config ()

		# Load external methods (if any)
		self._load_extra_methods ()

		self._check_dirs = []
		self._check_dbs  = []


	def _xxxcfg ( self, name, def_val = {} ):
		"""
		_cfg has been changed into a function.

		Now ``name`` can be a module attribute or a global system attribute.
		"""
		return self.__cfg #.get ( name, self.liwe.cfg.get ( name, def_val ) )


	def _load_extra_methods ( self ):
		fname = os.path.join ( "site", "modules", self.name, "cbacks", self.name + ".py" )
		if os.path.isfile ( fname ):
			cnt = open ( fname ).read ()
			cnt = self.__class__.__name__ + " = self.__class__\n" + cnt
			exec cnt

	def _read_dict ( self, dest, fname ):
		#sys.stderr.write ( "*** LOAD: %s\n" % fname )
		if os.path.isfile ( fname ):
			data = file ( fname ).read ().replace ( "\t", "" ).replace ( "\r", "\n" )
			dct = eval ( data )
			dest.update ( dct )

	def _read_db_dict ( self, dest, table_name, module_name, user_id ):
		data = self.dbm.single_row ( table_name, [ "data" ], "module_name = '%s' AND uid = '%s'" % ( module_name, user_id ) )
		if not data: return

		data = self.dbm.unpickle ( data [ 'data' ] )
		dest.update ( data )

	def _load_templates ( self ):
		# Load module default templates (in modules/(module_name)/templates/(module_name).txt)
		self._read_dict ( self.templates, os.path.join ( "modules", self.name, "templates", self.name + ".txt" ) )
		# Load user defined module templates (in site/modules/(module_name)/templates/(module_name).txt)
		self._read_dict ( self.templates, os.path.join ( "site", "modules", self.name, "templates", self.name + ".txt" ) )

		self.liwe.layman.templates_add ( self.name, self.templates )

	def _load_config ( self ):
		# Load module default config (in modules/(module_name)/config/(module_name).cfg)
		self._read_dict ( self.config, os.path.join ( "modules", self.name, "config", self.name + ".cfg" ) )
		# Load user defined module templates (in site/modules/(module_name)/config/(module_name).cfg)
		self._read_dict ( self.config, os.path.join ( "site", "modules", self.name, "config", self.name + ".cfg" ) )

		# Load DB module config (default is user "0" [not logged in])
		self._read_db_dict ( self.config, "liwe_config", self.name, self.pyhp.session.data.get ( "uid", 0 ) )

	def get_templates ( self ):
		return self.templates

	def list_perms ( self ):
		return self.liwe.invoke ( self.name + ".__init__.list_perms", None )

	def get_media_items ( self, id_obj, full = False ):
		try:
			from modules.media_manager.media_manager_class import MediaManager
			mm = MediaManager ( self.liwe )

			res = mm.get_items ( self.name, id_obj )
			if full:
				return res
			else:
				return res.get ( "media_items" )
		except:
			raise
			return []

	def check ( self, cfg_data ):
		#mod = __import__ ( "modules.%s" % self.name )
		#if not hasattr ( mod, "_cfg_data" ): return []

		files = cfg_data.get ( "files", [] )

		res = []
		for f in files:
			name = f [ 'name' ]
			if os.path.exists ( name ):
				res.append ( { "name" : name, "descr" : "found", "status" : "OK" } )		
			else:
				if f.get ( "mandatory" ):
					res.append ( { "name" : name, "descr" : "not found", "status" : "KO" } )		
				else:
					res.append ( { "name" : name, "descr" : "not found", "status" : "OK" } )		

		dirs = cfg_data.get ( "dirs", [] )
		for f in dirs:
			name = f [ 'name' ]
			if os.path.exists ( name ):
				if f.get ( "perms" ):
					st = os.stat ( name )
					o = str ( oct ( st.st_mode ) ) [ -3 : ]
					p = str ( f [ 'perms' ] )
					if o == p:
						res.append ( { "name" : name, "descr" : "found and valid permissions", "status" : "OK" } )		
					else:
						res.append ( { "name" : name, "descr" : "found and invalid permissions: %s / %s" % ( o, p ), "status" : "KO" } )		

				else:
					res.append ( { "name" : name, "descr" : "found", "status" : "OK" } )		
			else:
				if f.get ( "mandatory" ):
					res.append ( { "name" : name, "descr" : "not found", "status" : "KO" } )		
				else:
					res.append ( { "name" : name, "descr" : "not found", "status" : "OK" } )		


		return res

	def get_url ( self, params ):
		"""
		get_url ( params ) -> str

		This method returns a valid URL related to the current module.
		The ``params`` is a dictionary with all the needed info to render the right page.
		"""

		if 'module' not in params:
			res = [ 'module', self.name ]
		else:
			res = []

		for k, v in params.iteritems ():
			res.append ( str ( k ) )
			res.append ( str ( v ) )

		return '/'.join ( res )

	def url_to_history ( self, params ):
		res = { '__m' : params.get ( "module", self.name ),
			'_page' : params.get ( "page", "home" ) }

		for k,v in params.iteritems ():
			if k in ( "module", "page" ): continue
			res [ k ] = v
		
		return "#" + ','.join ( [ "%s=%s" % ( k, v ) for k, v in res.iteritems () ] )

	def sitemap_encode ( self, loc, lastmod = '', changefreq = '', priority = 1 ):
		import urllib

		remap = (
			( "&", "&amp;" ),
			( "'", "&apos;" ),
			( '"', "&quot;" ),
			( " ", "%20" ),
			( ">", "&gt;" ),
			( "<", "&lt;" )
		)

		for c in remap:
			loc = loc.replace ( c [ 0 ], c [ 1 ] )

		res = {}
		res [ 'loc' ] = "%s/%s" % ( self.liwe.base_url, loc )
		res [ 'priority' ] = priority

		if lastmod:  	res [ 'lastmod' ] = lastmod
		if changefreq: 	res [ 'changefreq' ] = changefreq

		return res
		

	def debug ( self ):
		return int ( self.liwe.cfg.get ( "debug.enabled", 0 ) )

